/*
 * Mapped files
 */

#ifndef FMAP_H_INCLUDED
#define FMAP_H_INCLUDED

#include <stdlib.h>

#include "reporting.h"

#define FMAP_ERRCODE_BASE           (2600)
#define FMAP_ERR_INVALID_SIZE       (FMAP_ERRCODE_BASE + 1)
#define FMAP_ERR_STAT_FAILED        (FMAP_ERRCODE_BASE + 2)
#define FMAP_ERR_TRUNCATE_FAILED    (FMAP_ERRCODE_BASE + 3)
#define FMAP_ERR_LSEEK_FAILED       (FMAP_ERRCODE_BASE + 4)
#define FMAP_ERR_WRITE_FAILED       (FMAP_ERRCODE_BASE + 5)
#define FMAP_ERR_MAP_TOO_BIG        (FMAP_ERRCODE_BASE + 6)
#define FMAP_ERR_ALIGNMENT_ERROR    (FMAP_ERRCODE_BASE + 7)
#define FMAP_ERR_MMAP_FAILED        (FMAP_ERRCODE_BASE + 8)

#define FMAP_READ       (1)
#define FMAP_WRITE      (2)
#define FMAP_READ_AHEAD (4)
#define FMAP_LOCKED     (16)
#define FMAP_NOSWAP     (32)

typedef struct _fmap_t
{
	int    fd;
	size_t map_size;
	size_t map_ahead_size;
	off_t  map_offset;
	int    prot;
	int    flags;
	void * addr;
} fmap_t;

typedef struct _fwindow_t
{
	fmap_t map;
	off_t  pos;
} fwindow_t;


#ifdef FMAP_INLINE_ALL
#define FMAP_STATIC static
#include "fmap.c"
#else
#define FMAP_STATIC
int fmap_init(fmap_t * self, int fd, int flags, size_t map_size, size_t map_ahead_size);
int fmap_fini(fmap_t * self);
void * fmap_map(fmap_t * self, off_t offset, size_t size);

int fwindow_init(fwindow_t * self, int fd, size_t map_size);
int fwindow_fini(fwindow_t * self);
int fwindow_write(fwindow_t * self, const void * buf, size_t size);
off_t fwindow_tell(fwindow_t * self);
void fwindow_advance(fwindow_t * self, off_t delta);
#endif


#endif /* FMAP_H_INCLUDED */
